package com.macro.mall.ums.service.account.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.macro.mall.common.api.exception.BusinessException;
import com.macro.mall.common.api.util.StringUtils;
import com.macro.mall.ums.domain.Member;
import com.macro.mall.ums.entity.MemberEntity;
import com.macro.mall.ums.enums.UserGenderEnum;
import com.macro.mall.ums.mapper.MemberMapper;
import com.macro.mall.ums.service.account.MemberService;
import com.macro.mall.ums.service.account.bo.InsertMemberInput;
import com.macro.mall.ums.service.account.bo.PagedQueryMemberInput;
import com.macro.mall.ums.service.account.bo.UpdateMemberInput;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 会员Service
 *
 * @author xuyanjun
 * @date 2019-12-09
 */
@Slf4j
@Service
public class MemberServiceImpl implements MemberService {

    @Autowired
    private MemberMapper memberMapper;

    /**
     * 生成邀请码
     *
     * @return 邀请码
     */
    @Override
    public String generateInvitationCode() {
        int maxLoopCount = 10;

        for (int i = 0; i < maxLoopCount; i++) {
            String invitationCode = StringUtils.getRandomNumberAndUpperLetters(6);
            MemberEntity userEntity = getByInvitationCode(invitationCode);
            if (userEntity == null) {
                return invitationCode;
            }
        }

        log.warn("生成邀请码超过最大重试次数。");

        throw new BusinessException("生成邀请码超过最大重试次数");
    }

    /**
     * 新增会员
     *
     * @param input input
     * @return 新增id
     */
    @Override
    public long insert(InsertMemberInput input) {
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setMemberLevelId(input.getMemberLevelId())
                .setUsername(input.getUsername())
                .setPassword(input.getPassword())
                .setNickname(input.getNickname())
                .setPhone(input.getPhone())
                .setStatus(1)
                .setIcon(input.getIcon())
                .setGender(input.getGender() == null ? UserGenderEnum.UNKNOW.getValue() : input.getGender().getValue())
                .setBirthday(input.getBirthday())
                .setCity(input.getCity())
                .setJob(input.getJob())
                .setPersonalizedSignature(input.getPersonalizedSignature())
                .setSourceType(input.getSourceType().getValue())
                .setIntegration(input.getIntegration())
                .setGrowth(input.getGrowth())
                .setLuckeyCount(input.getLuckeyCount())
                .setHistoryIntegration(input.getHistoryIntegration())
                .setLevel(input.getLevel())
                .setInvitationCode(input.getInvitationCode())
                .setBefId(input.getBefId());

        LocalDateTime now = LocalDateTime.now();
        memberEntity.setCreateTime(now);

        memberMapper.insert(memberEntity);
        return memberEntity.getId();
    }

    @Override
    public void updateBefId(long userId, long befId) {
        Assert.isTrue(userId > 0, "用户id不能为空。");
        Assert.isTrue(befId > 0, "上级id不能为空。");
        Assert.isTrue(userId != befId, "上级不能改成自己");

        List<MemberEntity> listBefUsers = listBefUsers(befId);

        Optional optional = listBefUsers.stream().filter(x -> x.getId() == userId).findFirst();

        Assert.isTrue(!optional.isPresent(), "下级不能成为上级的上级");

        memberMapper.updateBefId(userId, befId);
    }

    /**
     * 修改会员
     *
     * @param input input
     */
    @Override
    public void update(UpdateMemberInput input) {
        MemberEntity memberEntity = memberMapper.selectById(input.getId());
        if (memberEntity == null) {
            throw new BusinessException(String.format("未能根据Id:%s找到指定的会员。", input.getId()));
        }

        memberEntity = new MemberEntity();
        memberEntity
                .setId(input.getId())
                .setMemberLevelId(input.getMemberLevelId())
                .setUsername(input.getUsername())
                .setPassword(input.getPassword())
                .setNickname(input.getNickname())
                .setPhone(input.getPhone())
                .setStatus(input.getStatus())
                .setCreateTime(input.getCreateTime())
                .setIcon(input.getIcon())
                .setGender(input.getGender())
                .setBirthday(input.getBirthday())
                .setCity(input.getCity())
                .setJob(input.getJob())
                .setPersonalizedSignature(input.getPersonalizedSignature())
                .setSourceType(input.getSourceType())
                .setIntegration(input.getIntegration())
                .setGrowth(input.getGrowth())
                .setLuckeyCount(input.getLuckeyCount())
                .setHistoryIntegration(input.getHistoryIntegration())
                .setLevel(input.getLevel())
                .setInvitationCode(input.getInvitationCode())
                .setBefId(input.getBefId());

        memberMapper.updateById(memberEntity);
    }

    /**
     * 删除会员
     *
     * @param id id
     */
    @Override
    public void delete(long id) {
        memberMapper.deleteById(id);
    }

    /**
     * 根据Id获取会员
     *
     * @param id id
     * @return 会员
     */
    @Override
    public MemberEntity getById(long id) {
        return memberMapper.selectById(id);
    }

    /**
     * 根据邀请码获取用户
     *
     * @param invitationCode 邀请码
     * @return 用户
     */
    @SuppressWarnings(value = {"Duplicates"})
    @Override
    public MemberEntity getByInvitationCode(String invitationCode) {
        Assert.isTrue(StringUtils.isNotBlank(invitationCode), "邀请码不能为空。");

        LambdaQueryWrapper<MemberEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(MemberEntity::getInvitationCode, invitationCode);

        List<MemberEntity> userEntities = memberMapper.selectList(queryWrapper);
        if (userEntities.size() > 0) {
            return userEntities.get(0);
        }
        return null;
    }

    /**
     * 根据批量Id获取会员
     *
     * @param batchIds 批量ids
     * @return 会员集合
     */
    @Override
    public List<MemberEntity> listByBatchIds(List<Long> batchIds) {
        if (batchIds == null || batchIds.isEmpty()) {
            return new ArrayList<>();
        }
        return memberMapper.selectBatchIds(batchIds);
    }

    /**
     * 获取用户的所有的上级
     *
     * @param userId 用户id
     * @return 用户的所有的上级
     */
    @Override
    public List<MemberEntity> listBefUsers(long userId) {
        Assert.isTrue(userId > 0, "用户id不能为空。");

        MemberEntity userEntity = getById(userId);
        Assert.notNull(userEntity, "用户不存在，id:" + userId);

        List<MemberEntity> userChain = new ArrayList<>();

        while (userEntity != null) {
            long currentUserId = userEntity.getId();

            Optional<MemberEntity> optionalUserEntity = userChain.stream().filter(x -> x.getId().equals(currentUserId)).findFirst();
            if (optionalUserEntity.isPresent()) {
                break;
            }

            userChain.add(userEntity);

            if (userEntity.getBefId() == null || userEntity.getBefId() == 0L) {
                break;
            }
            userEntity = getById(userEntity.getBefId());
        }

        return userChain;
    }

    /**
     * 分页查询
     *
     * @param input input
     * @return 分页的会员
     */
    @Override
    public Page<MemberEntity> pagedQuery(PagedQueryMemberInput input) {
        LambdaQueryWrapper<MemberEntity> queryWrapper = Wrappers.lambdaQuery();

        if (input.getBefId() != null) {
            queryWrapper.eq(MemberEntity::getBefId, input.getBefId());
        }
        if (input.getUserId() != null) {
            queryWrapper.eq(MemberEntity::getId, input.getUserId());
        }
        if (input.getLevel() != null) {
            queryWrapper.eq(MemberEntity::getLevel, input.getLevel());
        }
        if (StringUtils.isNotBlank(input.getPhone())) {
            queryWrapper.eq(MemberEntity::getPhone, input.getPhone());
        }
        if (StringUtils.isNotBlank(input.getNickname())) {
            queryWrapper.like(MemberEntity::getNickname, input.getNickname());
        }

        PageHelper.startPage(input.getPageIndex(), input.getPageSize());

        return (Page<MemberEntity>) memberMapper.selectList(queryWrapper);
    }

    /**
     * 获取粉丝数量
     *
     * @param userId 用户id
     * @return 粉丝数量
     */
    @Override
    public long countOfFans(long userId) {
        LambdaQueryWrapper<MemberEntity> queryWrapper = Wrappers.lambdaQuery();

        queryWrapper.eq(MemberEntity::getBefId, userId);

        return memberMapper.selectCount(queryWrapper);
    }

    /**
     * 将实体对象转换成domain对象
     *
     * @param memberEntity 实体
     * @return member
     */
    @Override
    public Member entityToDomain(MemberEntity memberEntity) {
        if (memberEntity == null) {
            return null;
        }

        Member member = new Member();
        member.setId(memberEntity.getId())
                .setUsername(memberEntity.getUsername())
                .setNickname(memberEntity.getNickname())
                .setPhone(memberEntity.getPhone())
                .setStatus(memberEntity.getStatus())
                .setIcon(memberEntity.getIcon())
                .setGender(memberEntity.getGender())
                .setBirthday(memberEntity.getBirthday())
                .setCity(memberEntity.getCity())
                .setJob(memberEntity.getJob())
                .setPersonalizedSignature(memberEntity.getPersonalizedSignature())
                .setSourceType(memberEntity.getSourceType())
                .setIntegration(memberEntity.getIntegration())
                .setGrowth(memberEntity.getGrowth())
                .setLuckeyCount(memberEntity.getLuckeyCount())
                .setHistoryIntegration(memberEntity.getHistoryIntegration())
                .setLevel(memberEntity.getLevel())
                .setInvitationCode(memberEntity.getInvitationCode())
                .setBefId(memberEntity.getBefId());

        return member;
    }

    /**
     * 将实体对象转换成domain对象
     *
     * @param memberEntities 实体
     * @return members
     */
    @Override
    public List<Member> entityToDomain(List<MemberEntity> memberEntities) {
        List<Member> result = new ArrayList<>();
        if (memberEntities == null) {
            return result;
        }

        for (MemberEntity memberEntity : memberEntities) {
            Member member = entityToDomain(memberEntity);
            result.add(member);
        }
        return result;
    }

}
